from Accounting.Fee.FeeBase import Fee
from DataAccess.DBConnFactory import DBConnFactory
from Common.DayCounter import *
from string import Template
from datetime import datetime


class FixedFee(Fee):
	def __init__(self, ref_date, entity, subtype, is_payment_date, is_redem, curncy):
	
		cursor = DBConnFactory().get_db_connection('ACCOUNTING').cursor()
		sql_tpl = Template('''select daycount,
									asset_base_on,
									ratio,
									effective_on,
									effective_level,
									TO_CHAR(inception,'yyyy-mm-dd'),
									curncy 
							from fee_conf
							where entity='${ENTITY}'
								and subtype='${TP}' ''')		
		cursor.execute(sql_tpl.substitute(ENTITY=entity.get_entity_id(), 
										TP=subtype))
		r = cursor.fetchall()
		if not r:
			raise RuntimeError(), ("Fee Config Error")

		self.daycount = r[0][0]
		self.asset_base_on = r[0][1]
		self.ratio = r[0][2]
		self.effective_on = r[0][3]
		self.effective_level = r[0][4]
		self.inception = datetime.strptime(r[0][5],'%Y-%m-%d').date()
		#self.inception = r[0][5].date()
		self.fee_subtype = subtype
		
		Fee.__init__(self, ref_date, r[0][6], is_payment_date, is_redem, entity)
	
	def calculate(self):
		#print 'debug,',self.ref_date.isoformat(),',',self.entity.get_entity_id(),'::',self.type()
		
		cursor = DBConnFactory().get_db_connection('ACCOUNTING').cursor()
		
		if self.effective_on:
			sql_tpl = Template('''select avpu from asset_value_ex			
								where entity='${ENTITY}' 
								and type='${TP}' 
								and ref_date=TO_DATE('${DATE}','yyyy-mm-dd') ''')						
			if self.effective_on[0] == 'L': # last value
				sql_tpl = Template('''select avpu from
									(select avpu,ref_date from asset_value_ex
										where entity = '${ENTITY}' 
											and type = '${TP}' 
											and ref_date < TO_DATE('${DATE}','yyyy-mm-dd')
										order by ref_date desc)
									where rownum<=1''')	
			cursor.execute(sql_tpl.substitute(ENTITY=self.entity.get_entity_id(),
												TP=self.effective_on[-3:],
												DATE=self.ref_date.isoformat()))
			r = cursor.fetchall()
			if not r:
				raise RuntimeError(), ("Asset Value Per Unit Error")	
			effective_value = r[0][0]
			if effective_value < self.effective_level:
				self.amt = 0.0
				return
		
		#Calculate Last Accrued Date
		sql_tpl = Template('''select nvl(max(ref_date),TO_DATE('${START}','yyyy-mm-dd'))
							from fee_schedule_ex
							where entity= '${ENTITY}'
							and subtype='${TP}' 
							and ref_date > TO_DATE('${START}','yyyy-mm-dd')
							and ref_date < TO_DATE('${END}','yyyy-mm-dd') ''')
		sql_text = sql_tpl.substitute(ENTITY=self.entity.get_entity_id(),
									TP=self.fee_subtype,
									START=self.inception.isoformat(),
									END=self.ref_date.isoformat())
		#print sql_text
		cursor.execute(sql_text)
		r = cursor.fetchall()
		if not r:
			raise RuntimeError(), ("Fee Schedule Error")	
		last_accrued_date = r[0][0].date()
		
		#Calculate Asset Value
		sql_tpl = Template('''select av 
							from asset_value_ex			
							where entity='${ENTITY}' 
							and type='${TP}' 
							and ref_date=TO_DATE('${DATE}','yyyy-mm-dd') ''')							
		if self.asset_base_on[0] == 'L': # last value
			sql_tpl = Template('''select av 
								from
								(select av,ref_date from asset_value_ex
									where entity = '${ENTITY}' 
										and type = '${TP}' 
										and ref_date < TO_DATE('${DATE}','yyyy-mm-dd')
									order by ref_date desc)
								where rownum<=1''')	
		cursor.execute(sql_tpl.substitute(ENTITY=self.entity.get_entity_id(),
											TP=self.asset_base_on[-3:],
											DATE=self.ref_date.isoformat()))
		r = cursor.fetchall()
		#tmp_sql_text = sql_tpl.substitute(ENTITY=self.entity.get_entity_id(),
		#									TP=self.asset_base_on[-3:],
		#									DATE=self.ref_date.isoformat())
		#print tmp_sql_text
		if not r:
			raise RuntimeError(), ("Asset Value Error")
		asset_value = r[0][0]
		
		t=get_daycounter(self.daycount).yearFraction(last_accrued_date,self.ref_date)
		self.amt = asset_value*t*self.ratio
		#print 'asset value', asset_value
		#print 'time', t
		#print 'mgt ratio', self.ratio
		
	def type(self):
		return self.fee_subtype
		
	def category(self):
		return 'PreGAVFee'